<?php if(! defined('HAS_POWER') ) exit('无权访问!');
/**
==============================================================================
 * Class FileCacheComponent GracePHP文件缓存类组件
 * @author 肖永标
 * @date 2014-12-09
==============================================================================
 */

class FileCacheComponent extends Component{

    /**
     * @var string $dir 缓存保存的文件夹
     */
    private $dir;

    /**
     * @var string $file 缓存保存的文件
     */
    private $file;


    /** 文件缓存初始化
     * @throws Exception
     */
    public function init()
    {
        $this->dir = CURRENT_MODULE . Config::getItem('webCache.dir');
        if(!is_dir($this->dir))
        {
            if (!mkdir($this->dir, 0777, true))
                throw new Exception('创建临时缓存目录失败，请重试!');
        }

        $this->file = $this->dir . '/' . sha1('cache') . '.cache';
        if(!file_exists($this->file))
            file_put_contents($this->file, '');
    }


    /** 设置文件缓存的键值
     * @param string $key 键的名称
     * @param mixed $value 对应的值
     * @return bool
     */
    public function set($key, $value)
    {
        if(is_array($value) || is_object($value))
            $value = serialize($value);

        $string = $key . '=' . $value . "\r\n";
        $cache = $this->_parseFile();
        if(array_key_exists($key, $cache))
        {
            $content = file_get_contents($this->file);
            $content = str_replace("$key=$cache[$key]", "$key=$value", $content);
            file_put_contents($this->file, $content);
        }
        else
        {
            file_put_contents($this->file, $string, FILE_APPEND);
        }

        return true;
    }


    /**
     * @param string $key 键的名称
     * @return mixed|string
     */
    public function get($key)
    {
        $cache = $this->_parseFile();
        if(array_key_exists($key, $cache))
        {
            $val = $cache[$key];
            if($this->_isSerialized($val))
                return unserialize($val);
            else
                return $val;
        }

        return false;
    }


    /** 删除缓存中某一个键
     * @param string $key 键的名称
     * @return bool
     */
    public function delete($key)
    {
        $cache = $this->_parseFile();
        if(array_key_exists($key, $cache))
        {
            $content = file_get_contents($this->file);
            $content = str_replace("$key=$cache[$key]\r\n", "", $content);
            file_put_contents($this->file, $content);
            return true;
        }

        return false;
    }


    /** 清空文件缓存
     * @return bool
     */
    public function flush()
    {
        file_put_contents($this->file, '');
        return true;
    }

    /** 判断数据是否是经过序列化的
     * @param string $data 序列化后的字符串
     * @return bool
     */
    private function _isSerialized($data)
    {
        $data = trim($data);
        if ('N;' == $data)
            return true;
        if (!preg_match('/^([adObis]):/', $data, $badions))
            return false;
        switch ($badions[1]) {
            case 'a' :
            case 'O' :
            case 's' :
                if (preg_match("/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data))
                    return true;
                break;
            case 'b' :
            case 'i' :
            case 'd' :
                if (preg_match("/^{$badions[1]}:[0-9.E-]+;\$/", $data))
                    return true;
                break;
        }
        return false;
    }


    /** 解析缓存文件
     * @return array
     */
    private function _parseFile()
    {
        $content = file_get_contents($this->file);
        $arr = explode("\r\n", $content);

        $cache = array();
        foreach($arr as $k=>$v)
        {
            $temp = explode('=', $v);
            $cache[$temp[0]] = $temp[1];
        }

        return $cache;
    }


    public function allowLoad()
    {
        return false;
    }
}